/*
 * MouseIdentView.java
 */

package mouseident;

import java.awt.Color;
import java.awt.Graphics;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.DecimalFormat;
import java.util.ArrayDeque;
import java.util.ArrayList;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;

/**
 * The application's main frame.
 */
public class MouseIdentView extends FrameView {

    ArrayList<Node> parcour = new ArrayList<Node>();
    ArrayDeque<Event> history = new ArrayDeque<Event>();
    
    boolean capturing;


    public MouseIdentView(SingleFrameApplication app) {
        super(app);

        initComponents();


        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String)(evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer)(evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = MouseIdentApp.getApplication().getMainFrame();
            aboutBox = new MouseIdentAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        MouseIdentApp.getApplication().show(aboutBox);
    }



  

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        NodesLeftTextField = new javax.swing.JTextField();
        NodesToVisitLabel = new javax.swing.JLabel();
        ClearButton = new javax.swing.JButton();
        ResetButton = new javax.swing.JButton();
        StartButton = new javax.swing.JButton();
        createRandomLabel1 = new javax.swing.JLabel();
        cntNodesTextField = new javax.swing.JTextField();
        createRandomLabel2 = new javax.swing.JLabel();
        createRandomMazeButton = new javax.swing.JButton();
        ToggleCreateButton = new javax.swing.JToggleButton();
        canvas = new mouseident.MouseIdentCanvas();
        SendButton = new javax.swing.JButton();
        jButton1 = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        openMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();
        FileOpener = new javax.swing.JFileChooser();

        mainPanel.setName("mainPanel"); // NOI18N

        jPanel2.setName("jPanel2"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(mouseident.MouseIdentApp.class).getContext().getResourceMap(MouseIdentView.class);
        NodesLeftTextField.setBackground(resourceMap.getColor("NodesLeftTextField.background")); // NOI18N
        NodesLeftTextField.setEditable(false);
        NodesLeftTextField.setText(resourceMap.getString("NodesLeftTextField.text")); // NOI18N
        NodesLeftTextField.setName("NodesLeftTextField"); // NOI18N

        NodesToVisitLabel.setText(resourceMap.getString("NodesToVisitLabel.text")); // NOI18N
        NodesToVisitLabel.setName("NodesToVisitLabel"); // NOI18N

        ClearButton.setText(resourceMap.getString("ClearButton.text")); // NOI18N
        ClearButton.setToolTipText(resourceMap.getString("ClearButton.toolTipText")); // NOI18N
        ClearButton.setName("ClearButton"); // NOI18N
        ClearButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ClearButtonActionPerformed(evt);
            }
        });

        ResetButton.setText(resourceMap.getString("ResetButton.text")); // NOI18N
        ResetButton.setToolTipText(resourceMap.getString("ResetButton.toolTipText")); // NOI18N
        ResetButton.setName("ResetButton"); // NOI18N
        ResetButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ResetButtonActionPerformed(evt);
            }
        });

        StartButton.setText(resourceMap.getString("StartButton.text")); // NOI18N
        StartButton.setToolTipText(resourceMap.getString("StartButton.toolTipText")); // NOI18N
        StartButton.setName("StartButton"); // NOI18N
        StartButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                StartButtonActionPerformed(evt);
            }
        });

        createRandomLabel1.setText(resourceMap.getString("createRandomLabel1.text")); // NOI18N
        createRandomLabel1.setName("createRandomLabel1"); // NOI18N

        cntNodesTextField.setText(resourceMap.getString("cntNodesTextField.text")); // NOI18N
        cntNodesTextField.setName("cntNodesTextField"); // NOI18N

        createRandomLabel2.setText(resourceMap.getString("createRandomLabel2.text")); // NOI18N
        createRandomLabel2.setName("createRandomLabel2"); // NOI18N

        createRandomMazeButton.setText(resourceMap.getString("createRandomMazeButton.text")); // NOI18N
        createRandomMazeButton.setToolTipText(resourceMap.getString("createRandomMazeButton.toolTipText")); // NOI18N
        createRandomMazeButton.setName("createRandomMazeButton"); // NOI18N
        createRandomMazeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                createRandomMazeButtonActionPerformed(evt);
            }
        });

        ToggleCreateButton.setText(resourceMap.getString("ToggleCreateButton.text")); // NOI18N
        ToggleCreateButton.setToolTipText(resourceMap.getString("ToggleCreateButton.toolTipText")); // NOI18N
        ToggleCreateButton.setName("ToggleCreateButton"); // NOI18N
        ToggleCreateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ToggleCreateButtonActionPerformed(evt);
            }
        });

        canvas.setBackground(resourceMap.getColor("canvas.background")); // NOI18N
        canvas.setName("canvas"); // NOI18N
        canvas.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                canvasMousePressed(evt);
            }
        });
        canvas.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                canvasMouseMoved(evt);
            }
        });

        SendButton.setText(resourceMap.getString("SendButton.text")); // NOI18N
        SendButton.setName("SendButton"); // NOI18N
        SendButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SendButtonActionPerformed(evt);
            }
        });

        jButton1.setText(resourceMap.getString("jButton1.text")); // NOI18N
        jButton1.setName("jButton1"); // NOI18N
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(StartButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(ResetButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(ClearButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(SendButton)
                    .addComponent(jButton1))
                .addGap(22, 22, 22)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(NodesToVisitLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(NodesLeftTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 402, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(createRandomLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cntNodesTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(createRandomLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(createRandomMazeButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 379, Short.MAX_VALUE)
                        .addComponent(ToggleCreateButton))
                    .addComponent(canvas, javax.swing.GroupLayout.PREFERRED_SIZE, 762, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cntNodesTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(createRandomLabel1)
                    .addComponent(createRandomLabel2)
                    .addComponent(createRandomMazeButton)
                    .addComponent(ToggleCreateButton)
                    .addComponent(StartButton))
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addComponent(canvas, javax.swing.GroupLayout.DEFAULT_SIZE, 475, Short.MAX_VALUE)
                        .addGap(4, 4, 4)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(NodesToVisitLabel)
                            .addComponent(NodesLeftTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(18, 18, 18)
                        .addComponent(ResetButton)
                        .addGap(18, 18, 18)
                        .addComponent(ClearButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 372, Short.MAX_VALUE)
                        .addComponent(jButton1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(SendButton)))
                .addContainerGap())
        );

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N

        openMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        openMenuItem.setText(resourceMap.getString("openMenuItem.text")); // NOI18N
        openMenuItem.setName("openMenuItem"); // NOI18N
        fileMenu.add(openMenuItem);

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(mouseident.MouseIdentApp.class).getContext().getActionMap(MouseIdentView.class, this);
        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 907, Short.MAX_VALUE)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 737, Short.MAX_VALUE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        FileOpener.setDialogTitle(resourceMap.getString("OpenFileChooser.dialogTitle")); // NOI18N
        FileOpener.setName("OpenFileChooser"); // NOI18N
        FileOpener.setRequestFocusEnabled(false);

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

  /**
     * creates a new node with random color.
     * @param X
     * @param Y
     */
    private void createNewNode(int X, int Y) {
        int r = (int) Math.round(Math.random() * 255);
            int g = (int) Math.round(Math.random() * 255);
            int b = (int) Math.round(Math.random() * 255);
        createNewNode(X, Y, new Color(r,g,b));
    }

    /**
     * creates a new Node at the given coordinates and draws it in the given color.
     * @param X x-coordinate
     * @param Y y-coordinate
     */
    private void createNewNode(int X, int Y, Color color) {
        NodesLeftTextField.setText(NodesLeftTextField.getText() + " " + parcour.size());
            int currentNodeIndex = parcour.size();
            
            // format the colorcode, to write it properly into the define file.
            String rs = new DecimalFormat("000").format(color.getRed());
            String gs = new DecimalFormat("000").format(color.getGreen());
            String bs = new DecimalFormat("000").format(color.getBlue());
            // add our new Node to the parcour
            parcour.add(new Node(X, Y, color));
            canvas.setParcour(parcour);
            canvas.repaint();
            currentNodeIndex++;
    }


    /**
     * when capturing, the movement is pushed into the history
     * @param evt
     */


    /**
     * fired when a mouse button is pressed on the canvas.
     * When in normal mode..
     *  ..and on a node: The node is marked visited and this incident is reported to the resultArea.
     *  ..and not on a node: The incident is reported to the resultArea.
     * when in create Mode:
     *  a node is created at the selected position.
     * @param evt
     */
    /**
     * parses a file with Information about Nodes and creates them.
     * @param evt not used
     */

    private void canvasMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_canvasMouseMoved
        if (!ToggleCreateButton.isSelected() && capturing) {
            Event newEvent = new Event();
            newEvent.setType(Event.MOVEMENT_TYPE);
            newEvent.setWhen(evt.getWhen());
            newEvent.setX(evt.getX());
            newEvent.setY(evt.getY());
            addToHistory(newEvent);
            Graphics g = canvas.getGraphics();
            g.setColor(new Color(0, 0, 255));
            g.drawRect(evt.getX(), evt.getY(), 1, 1);
        }
}//GEN-LAST:event_canvasMouseMoved

    private void canvasMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_canvasMousePressed
        boolean through = true;
        boolean visited = false;
        // check if we are in normal mode and then if we are capturing
        if (!ToggleCreateButton.isSelected()) {
            if (capturing) {
                NodesLeftTextField.setText("");
                // check if we hit a Node
                for (Node d : parcour) {
                    if (d.isInArea(evt.getX(), evt.getY())) {
                        // if yes, mark it visited and mark it as a hit
                        d.setVisited(true);
                        addToHistory(new Event(parcour.indexOf(d), evt.getWhen(), evt.getX(), evt.getY()));
                        visited = true;
                    }
                    // if there is an unvisited Node, we're not yet through the maze
                    if (d.isVisited() == false) {
                        NodesLeftTextField.setText(NodesLeftTextField.getText() + " " + parcour.indexOf(d));
                        through = false;
                    }
                }
                if (! visited) {
                    // we didn't hit a node, but we still want the info, that the button was pressed
                    addToHistory(new Event(Event.CLICK_TYPE, evt.getWhen(), evt.getX(), evt.getY()));
                }
                // when we're through the maze, say that in the results and stop capturing
                if (through) {
                    addToHistory(new Event(Event.FINISH_TYPE, evt.getWhen(), evt.getX(), evt.getY()));
                    capturing = false;
                    StartButton.setEnabled(true);
                    StartButton.setText("Start");
                }
                canvas.setParcour(parcour);
               // canvas.repaint();
            }
        } else { // we are in create mode
            createNewNode(evt.getX(), evt.getY());
        }
}//GEN-LAST:event_canvasMousePressed

    private void ToggleCreateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ToggleCreateButtonActionPerformed
        System.out.println(evt.getActionCommand());
        if (ToggleCreateButton.isSelected()) {
            ClearButtonActionPerformed(evt);
            ToggleCreateButton.setText("Switch to normal Mode");
        } else {
            ToggleCreateButton.setText("Switch to create Mode");
        }
}//GEN-LAST:event_ToggleCreateButtonActionPerformed

    private void createRandomMazeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createRandomMazeButtonActionPerformed
        ClearButtonActionPerformed(evt);
        for (int i = 0; i < Integer.parseInt(cntNodesTextField.getText()); i++) {
            int x = 0;
            int y = 0;
            boolean overlaps = false;

            do { // create new coordinates until a non overlapping spot is found
                overlaps = false;
                x = (int) (Math.round(Math.random() * (canvas.getWidth() - 40)) + 20); // stay away from the borders
                y = (int) (Math.round(Math.random() * (canvas.getHeight() - 40)) + 20);
                for (Node n : parcour) {
                    if (n.overlaps(new Node(x, y, new Color(0,0,0)))) {
                        overlaps = true;
                    }
                }
            } while (overlaps);

            createNewNode(x, y);
        }
}//GEN-LAST:event_createRandomMazeButtonActionPerformed

    private void StartButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_StartButtonActionPerformed
        capturing = true;
        StartButton.setText("running");
        StartButton.setEnabled(false);
}//GEN-LAST:event_StartButtonActionPerformed

    private void SendButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SendButtonActionPerformed
        Result result = new Result();
        result.setHistory(history);
        result.setParcour(parcour);
        JFrame mainFrame = MouseIdentApp.getApplication().getMainFrame();
        SaveDialog savedialog = new SaveDialog(mainFrame, result);
        savedialog.setLocationRelativeTo(mainFrame);
        MouseIdentApp.getApplication().show(savedialog);
}//GEN-LAST:event_SendButtonActionPerformed

    private void ResetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ResetButtonActionPerformed
        capturing = false;
        history.clear();
        NodesLeftTextField.setText("");
        for (Node d: parcour) {
            d.setVisited(false);
        }
        canvas.setParcour(parcour);
        canvas.repaint();
        StartButton.setEnabled(true);
        StartButton.setText("Start");
}//GEN-LAST:event_ResetButtonActionPerformed

    private void ClearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ClearButtonActionPerformed
        parcour.clear();
        canvas.setParcour(parcour);
        canvas.getGraphics().clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
        history.clear();
        NodesLeftTextField.setText("");
        capturing = false;
        StartButton.setEnabled(true);
        StartButton.setText("Start");
}//GEN-LAST:event_ClearButtonActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        File f  = new File("C:/Users/matze/slow.csv");
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(f));
            for (Event e: history) {
                String line = "0," + "20," + e.getWhen() + "," + e.getType() + "," + e.getX() + "," + e.getY() + "," + e.getDeltaT() + "," + e.getDistance();
                bw.write(line + "\n");
            }
            bw.close();
        } catch (IOException ex) {
            Logger.getLogger(MouseIdentView.class.getName()).log(Level.SEVERE, null, ex);
        }


    }//GEN-LAST:event_jButton1ActionPerformed

    /**
     * Toggles to the create mode or the normal mode. In create Mode the user can create a maze of nodes.
     * In normal mode the movement can be captured.
     * @param evt
     */
    /**
     * Starts capturing.
     * @param evt
     */

    /**
     * Resets so the user can take this maze again.
     * @param evt
     */
    /**
     * Creates a random maze with as much nodes as the user specified in cntNodesTextField.
     * @param evt
     */
    /**
     * saves the content of ResultArea to a file.
     * @param evt
     */
    /**
     * clears everything.
     * @param evt
     */
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton ClearButton;
    private javax.swing.JFileChooser FileOpener;
    private javax.swing.JTextField NodesLeftTextField;
    private javax.swing.JLabel NodesToVisitLabel;
    private javax.swing.JButton ResetButton;
    private javax.swing.JButton SendButton;
    private javax.swing.JButton StartButton;
    private javax.swing.JToggleButton ToggleCreateButton;
    private mouseident.MouseIdentCanvas canvas;
    private javax.swing.JTextField cntNodesTextField;
    private javax.swing.JLabel createRandomLabel1;
    private javax.swing.JLabel createRandomLabel2;
    private javax.swing.JButton createRandomMazeButton;
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem openMenuItem;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    // End of variables declaration//GEN-END:variables

    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;

    private JDialog aboutBox;

    


    /**
     * calculates deltas for given event and adds it to history.
     */
    private void addToHistory(Event ev) {
        if (!history.isEmpty())  {
            Event last = history.getLast();
            // if this and the last event are movements and they happened in the same
            // millisecond, we need to calculate the mean position and use that.
            if ( ev.getType() == Event.MOVEMENT_TYPE && last.getType() == Event.MOVEMENT_TYPE
                    && last.getWhen() == ev.getWhen()) {
                history.remove(last);
                ev.setX((last.getX() + ev.getX()) / 2);
                ev.setY((last.getY() + ev.getY()) / 2);

            }

            // Calculate deltas
            long deltaT = last.getDeltaT() + (ev.getWhen() - last.getWhen());
            double deltaX = ev.getX() - last.getX();
            double deltaY = ev.getY() - last.getY();
            long distance = last.getDistance() + Math.round(Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)));

            //write deltas
            ev.setDeltaT(deltaT);
            ev.setDistance(distance);


        }
        history.addLast(ev);
    }
}
